package br.com.viamais.mb;

import javax.faces.bean.ManagedBean;
import javax.faces.context.FacesContext;

import br.com.viamais.enumerator.Permission;
import br.com.viamais.model.Role;
import br.com.viamais.model.User;
import br.com.viamais.util.ManagerLogin;
import br.com.viamais.util.MessageBundleUtil;

/**
 * <B>Project: viamais-web</B><BR>
 * 
 * This is the main managed bean to control all restrictions configuring the view to the user logged.
 * This class contains methods to check user restrictions, login, and session invalidation issues.
 * 
 * <DL>
 * <DT><B>Created:</B>
 * <DD>Oct 20, 2011</DD></DT>
 * </DL>
 * <DL>
 * <DT><B>Last Modification:</B>
 * <DD>Oct 20, 2011</DD></DT>
 * </DL>
 * 
 * @author Caio Carleto - CarSer - Oct 20, 2011
 * @version 1.0
 */
@ManagedBean
public class LoginMB extends BaseMB {
	
	/**
	 * Action doLogin.
	 */
	private static final String ACTION_DOLOGIN = "userSearch";
	/**
	 * Action doLogoff.
	 */
	//TODO check the use of this constant
	private static final String ACTION_DOLOGOFF = MessageBundleUtil
			.getValue("manager.action.login.dologoff");
	/**
	 * Welcome message.
	 */
	private static final String MESSAGE_DOLOGIN_SUCESS = MessageBundleUtil
			.getValue("manager.message.login.dologin.success");
	/**
	 * Login failure message.
	 */
	private static final String MESSAGE_DOLOGIN_FAILURE = MessageBundleUtil
			.getValue("manager.message.login.dologin.failure");
	/**
	 * Fatal error message.
	 */
	private static final String MESSAGE_FATAL = MessageBundleUtil
			.getValue("manager.message.generic.error.connection");
	/**
	 * Log off success message.
	 */
	//TODO check the use of this constant.
	private static final String MESSAGE_DOLOGOFF_SUCESS = MessageBundleUtil
			.getValue("manager.message.login.dologoff.success");
	
	
	private String username;
	private String password;
	
	private User user;
	
	private Boolean userReader;
	private Boolean userCreator;
	private Boolean userDeleter;
	private Boolean profileReader;
	private Boolean profileCreator;
	private Boolean profileDeleter;
	
	/**
	 * @return the user name
	 */
	public String getUsername() {
		return username;
	}
	
	/**
	 * @param username
	 *            the user name to set
	 */
	public void setUsername(String username) {
		this.username = username;
	}

	/**
	 * @return the password
	 */
	public String getPassword() {
		return password;
	}

	/**
	 * @param password
	 *            the password to set
	 */
	public void setPassword(String password) {
		this.password = password;
	}

	/**
	 * {@inheritDoc}
	 */
	public void reset() {
		this.username = null;
		this.password = null;
		this.user = null;
		this.userReader = null;
		this.userDeleter = null;
		this.userCreator = null;
		this.profileReader = null;
		this.profileDeleter = null;
		this.profileCreator = null;
	}

	/**
	 * To user log in.
	 * 
	 * @return String: action.
	 */
	public String doLogin() {
		String pageRedirect = null;
		
		try {
			if(user != null) {
				pageRedirect = ACTION_DOLOGIN;
			} else {
				user = ManagerLogin.doLogin(username, password);
				if (user == null) {
					this.addFacesMessage(MessageType.MESSAGE_ERROR,
							MESSAGE_DOLOGIN_FAILURE);
				} else {
					this.getContextPermissions();
					this.addFacesMessage(MessageType.MESSAGE_SUCESS,
							MESSAGE_DOLOGIN_SUCESS + user.getName());
					pageRedirect = ACTION_DOLOGIN;
				}
			}
		} catch (Throwable e) {
			this.addFacesMessage(MessageType.MESSAGE_FATAL, MESSAGE_FATAL);
			e.printStackTrace();
		}
		return pageRedirect;
	}

	/**
	 * To user log off
	 * 
	 * @return String: action.
	 */
	public String doLogoff() {
		try {
			//TODO Check the commented lines of this method, and the return (was calling ACTION_DOLOGOFF before).
//			ManagerLogin.doLogoff();
			reset();
			FacesContext.getCurrentInstance().getExternalContext().invalidateSession();
//			this.addFacesMessage(MessageType.MESSAGE_SUCESS,
//					MESSAGE_DOLOGOFF_SUCESS);
		} catch (Throwable e) {
			e.printStackTrace();
			return null;
		}
		return "login";
	}
	
	/**
	 * Auxiliary method to configure permissions accordingly to the user roles.
	 *
	 * @author Caio Carleto CarSer - Oct 20, 2011
	 *
	 * @version 1.0
	 */
	private void getContextPermissions() {
		for (Role role : user.getProfile().getRoles()) {
			getUserRoles(role);
			getProfileRoles(role);
		}
	}
	
	/**
	 * Auxiliary method that configure what the user can view about the user-related registry.
	 *
	 * @param role - actual role to be compared between Permission Enum User-related restrictions.
	 *  
	 * @author Caio Carleto CarSer - Oct 20, 2011
	 *
	 * @version 1.0
	 */
	private void getUserRoles(Role role) {
		if(role.getPermission().equals(Permission.READ_USER)) {
			userReader = true;
		}
		if(role.getPermission().equals(Permission.CREATE_USER)) {
			userCreator = true;
		}
		if(role.getPermission().equals(Permission.DELETE_USER)) {
			userDeleter = true;
		}
	}
	
	/**
	 * Auxiliary method that configure what the user can view about the profile-related registry.
	 *
	 * @param role - actual role to be compared between Permission Enum profile-related restrictions.
	 *  
	 * @author Caio Carleto CarSer - Oct 20, 2011
	 *
	 * @version 1.0
	 */
	private void getProfileRoles(Role role) {
		if(role.getPermission().equals(Permission.READ_PROFILE)) {
			profileReader = true;
		}
		if(role.getPermission().equals(Permission.CREATE_PROFILE)) {
			profileCreator = true;
		}
		if(role.getPermission().equals(Permission.DELETE_PROFILE)) {
			profileDeleter = true;
		}
	}

	public User getUser() {
		return user;
	}

	public Boolean getUserReader() {
		return userReader;
	}

	public Boolean getUserCreator() {
		return userCreator;
	}

	public Boolean getUserDeleter() {
		return userDeleter;
	}

	public Boolean getProfileReader() {
		return profileReader;
	}

	public Boolean getProfileCreator() {
		return profileCreator;
	}

	public Boolean getProfileDeleter() {
		return profileDeleter;
	}

}
